package com.internetCafes.spms.common.aspect;

import com.internetCafes.spms.common.CommonConstants;
import com.internetCafes.spms.core.annotation.DataFilter;
import com.internetCafes.spms.core.exception.RRException;
import com.internetCafes.spms.common.utils.ShiroUtils;
import com.internetCafes.spms.web.sys.model.UserInfo;
import com.internetCafes.spms.web.sys.service.DeptInfoService;
import com.internetCafes.spms.web.sys.service.RoleDeptInfoService;
import com.internetCafes.spms.web.sys.service.UserRoleInfoService;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 数据过滤，切面处理类
 * @author Sunny
 * @email rekeeper2011@hotmail.com
 * @date 2017/9/17 15:02
 */
@Aspect
@Component
public class DataFilterAspect {

    @Autowired
    private DeptInfoService deptInfoService;

    @Autowired
    private UserRoleInfoService userRoleInfoService;

    @Autowired
    private RoleDeptInfoService roleDeptInfoService;



    @Pointcut("@annotation(com.internetCafes.spms.core.annotation.DataFilter)")
    public void dataFilterCut() {

    }



    @Before("dataFilterCut()")
    public void dataFilter(JoinPoint point) throws Throwable {
        Object params = point.getArgs()[0];
        if(params != null && params instanceof Map){
            UserInfo user = ShiroUtils.getUserEntity();
            //如果不是超级管理员，则只能查询本部门及子部门数据
            if(user.getId() != CommonConstants.SUPER_ADMIN){
                Map map = (Map)params;
                String filterSql = getFilterSQL(user, point, map);
                map.put("filterSql", filterSql);
            }

            return ;
        }

        throw new RRException("要实现数据权限接口的参数，只能是Map类型，且不能为NULL");
    }



    /**
     * 获取数据过滤的SQL
     */
    private String getFilterSQL(UserInfo user, JoinPoint point, Map<String, Object> params){
        MethodSignature signature = (MethodSignature) point.getSignature();
        DataFilter d = signature.getMethod().getAnnotation(DataFilter.class);
        String tableAlias = d.tableAlias();
        if(StringUtils.isNotBlank(tableAlias)){
            tableAlias +=  ".";
        }

        List<Long> resultDeptIds = new ArrayList<>();
        List<Long> roleIds = userRoleInfoService.queryRoleIdList(user.getId());
        if(roleIds != null && roleIds.size() > 0){
            List<Long> deptIds;
            if(roleIds.size() == 1){
                deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(0));
                if(deptIds != null && deptIds.size() > 0){
                    resultDeptIds.addAll(deptIds);
                }
            } else {
                deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(0));
                if(deptIds != null && deptIds.size() > 0){
                    resultDeptIds.addAll(deptIds);
                }
                for(int i=1; i < roleIds.size(); i++){
                    deptIds = roleDeptInfoService.queryDeptIdList(roleIds.get(i));
                    if(deptIds != null && deptIds.size() > 0){
                        for(Long deptId:deptIds){
                            if(!resultDeptIds.contains(deptId)){
                                resultDeptIds.add(deptId);
                            }
                        }
                    }
                }
            }
        }


        StringBuilder sql = new StringBuilder();
        if(resultDeptIds.size() == 0 && !d.user()){
            return "";
        } else if(resultDeptIds.size() != 0 && d.user()){
            sql.append("AND (").append(tableAlias).append("DEPT_ID IN(").append(StringUtils.join(resultDeptIds, ",")).append(")");
            sql.append(" OR ").append(tableAlias).append("CREATE_BY=").append(user.getId());
            sql.append(")");
        } else {
            if(resultDeptIds.size() != 0){
                sql.append("AND ").append(tableAlias).append("DEPT_ID IN(").append(StringUtils.join(resultDeptIds, ",")).append(")");
            } else if(d.merge() && params.containsKey("mergeMap")){
                Map<String, Object> mergeMap = (Map)params.get("mergeMap");
                params.putAll(mergeMap);
            }

            if(d.user()){
                sql.append(" AND ").append(tableAlias).append("CREATE_BY=").append(user.getId());
            }
        }


        return sql.toString();
    }
}
